#include "mainwindow.h"
#include <QDockWidget>
#include <QPushButton>
#include <QLabel>
#include <QMenuBar>
#include <QMenu>
#include <QStatusBar>
#include <QVBoxLayout>
#include "messagelog.h"
#include <QTimer>
#include <QFileDialog>
#include "audiodataprocess.h"
#include "widget_ir.h"


#if (defined QDEBUG_REDIRECTION) && (QDEBUG_REDIRECTION)
MainWindow *MainWindow::myMsg = nullptr;
#endif
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QMenuBar *menuBar;
    QMenu *menuView;
    // QMenu *menuEffect;
    QStatusBar *statusBar;

    resize(800,600);

    menuBar = new QMenuBar(this);
    // menuBar->setGeometry(QRect(0, 0, 200, 21));
    // menuEffect = new QMenu(menuBar);
    // menuEffect->setTitle(tr("效果"));
    // menuBar->addAction(menuEffect->menuAction());
    menuView = new QMenu(menuBar);
    menuView->setTitle(tr("显示"));
    menuBar->addAction(menuView->menuAction());

    this->setMenuBar(menuBar);
    statusBar = new QStatusBar(this);
    this->setStatusBar(statusBar);
    // btn_open_device = new QPushButton(tr("Open"));
    // lab_device_info = new QLabel(tr("No Device"));
    // statusBar->addPermanentWidget(lab_device_info);
    // statusBar->addPermanentWidget(btn_open_device);

    // connect(this,&MainWindow::show_status_bar_message,statusBar,&QStatusBar::showMessage);
    // connect(btn_open_device,&QPushButton::clicked,this,&MainWindow::btn_click_open_device);

    // 创建停靠管理器 由于父参数是 QMainWindow，因此停靠管理器会将自己注册为中心部件。
    m_DockManager = new ads::CDockManager(this);

    // 创建示例内容标签--可以是任何特定于应用程序的部件
    MessageLog* logger = new MessageLog();
    logger->set_text("");
    // logger->setAttribute(Qt::WA_QuitOnClose,false);
#if (defined QDEBUG_REDIRECTION) && (QDEBUG_REDIRECTION)
    myMsg = this;
    qInstallMessageHandler(customMessageHandler);
    connect(this,&MainWindow::sig_send_message_static,this,&MainWindow::append_text_static);
#endif
    connect(this,&MainWindow::append_message,logger,&MessageLog::append_log_text);

    // 创建一个标题为 "标签 1 "的停靠 widget，并将创建的标签设置为停靠 widget 的内容
    ads::CDockWidget* dw;
    dw = new ads::CDockWidget("Logger");
    dw->setWidget(logger);
    dw->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromDockWidget);
    menuView->addAction(dw->toggleViewAction());// 在菜单中添加停靠窗口小部件的切换视图操作（toggleViewAction），让用户可以在停靠窗口小部件关闭时将其显示出来。
    m_DockManager->addDockWidget(ads::BottomDockWidgetArea, dw);// 将停靠窗口小部件添加到顶部停靠窗口小部件区域

    AudioDataProcess *adp = new AudioDataProcess;
    Widget_IR* ir_page = new Widget_IR(adp);
    dw = new ads::CDockWidget("IR");
    dw->setWidget(ir_page);
    dw->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromDockWidget);
    connect(ir_page,&Widget_IR::windowTitleChanged,dw,&ads::CDockWidget::setWindowTitle);
    menuView->addAction(dw->toggleViewAction());// 在菜单中添加停靠窗口小部件的切换视图操作（toggleViewAction），让用户可以在停靠窗口小部件关闭时将其显示出来。
    m_DockManager->addDockWidget(ads::TopDockWidgetArea, dw);// 将停靠窗口小部件添加到顶部停靠窗口小部件区域

    // AudioDevice *viewAudioDevices = new AudioDevice(this);
    // dw = new ads::CDockWidget("音频设备");
    // dw->setWidget(viewAudioDevices);
    // dw->setMinimumSizeHintMode(ads::CDockWidget::MinimumSizeHintFromDockWidget);
    // connect(ir_page,&Widget_IR::windowTitleChanged,dw,&ads::CDockWidget::setWindowTitle);
    // menuView->addAction(dw->toggleViewAction());
    // m_DockManager->addDockWidget(ads::RightAutoHideArea, dw);


    // m_audioSource = new QAudioSource(viewAudioDevices->get_input_device(), formatAudio);
    // m_audioSource->setBufferSize(2000);
    // m_audioSource->start(m_device);


//     command_process = new CommandProcess;
//     usb_communication = new USBCommunication;
//     connect(this,&MainWindow::usb_device_change,usb_communication,&USBCommunication::usb_device_change);
//     connect(usb_communication,&USBCommunication::usb_device_receive_new_data, command_process,&CommandProcess::receive_data,Qt::QueuedConnection);
//     connect(usb_communication,&USBCommunication::usb_device_is_connect,this,&MainWindow::usb_device_is_connect);
//     connect(usb_communication,&USBCommunication::usb_device_is_disconnect,this,&MainWindow::usb_device_is_disconnect);
//     usb_communication->usb_device_init(0x8085,0x2000,3);
//     if(usb_communication->usb_device_start_hotplug() != USBCommunication::SUCCESS)
//     {
// #if defined Q_OS_WIN
//         RegisterUSBDeviceNotification();
// #endif
//     }
//     usb_communication->usb_device_connect();


}

MainWindow::~MainWindow()
{

}

void MainWindow::closeEvent(QCloseEvent* event)
{
    // 确保所有的窗口都关闭
    m_DockManager->deleteLater();
    QMainWindow::closeEvent(event);
}


#if defined Q_OS_WIN
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long long *result)
{
    PMSG msg = (PMSG)message;
    UINT msgType = msg->message;
    if(msgType == WM_DEVICECHANGE)
    {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
        switch(msg->wParam)
        {
        case DBT_DEVICETYPESPECIFIC:
        {
            qDebug() << "DBT_DEVICETYPESPECIFIC " ;
            break;
        }
        case DBT_DEVICEARRIVAL:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
            {
                PDEV_BROADCAST_DEVICEINTERFACE pDevInf  = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
                // QString device_name = QString::fromWCharArray((const wchar_t *)pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
                QString device_name = QString::fromWCharArray((const wchar_t *)pDevInf->dbcc_name).toUtf8();
                QString strVID,strPID,strSerialNumber;
                strVID = device_name.mid(12,4);
                strPID = device_name.mid(21,4);
                strSerialNumber = device_name.section('#',2,2);
                uint16_t vid=0,pid=0;
                bool ok;
                vid = strVID.toUInt(&ok,16);
                pid = strPID.toUInt(&ok,16);
                emit usb_device_change(true,vid,pid,strSerialNumber);
                emit show_status_bar_message("device arrival:" + device_name,2000);
            }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
            {
                PDEV_BROADCAST_DEVICEINTERFACE pDevInf  = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
                // QString device_name = QString::fromWCharArray((const wchar_t *)pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
                QString device_name = QString::fromWCharArray((const wchar_t *)pDevInf->dbcc_name).toUtf8();
                QString strVID,strPID,strSerialNumber;
                strVID = device_name.mid(12,4);
                strPID = device_name.mid(21,4);
                strSerialNumber = device_name.section('#',2,2);
                uint16_t vid=0,pid=0;
                bool ok;
                vid = strVID.toUInt(&ok,16);
                pid = strPID.toUInt(&ok,16);
                emit usb_device_change(false,vid,pid,strSerialNumber);
                emit show_status_bar_message("device remove:" + device_name,2000);
            }
            break;
        case DBT_DEVNODES_CHANGED:
        {

        }
        break;
        }
    }
    return false;
}

const GUID GUID_DEVICEINTERFACE_LIST[] = {
    // {0x8FA230A2, 0xEBF0, 0x4C49, { 0xA2, 0xD6, 0x5A, 0x84, 0x85, 0x3B, 0x64, 0xD7 } },
    // {0xa5dcbf10, 0x6530, 0x11d2, { 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } },
    {0x60000001, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
};

#pragma comment(lib, "user32.lib")
bool MainWindow::RegisterUSBDeviceNotification(void)
{
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    HDEVNOTIFY hDeviceNotify;

    ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    for(int i=0; i<sizeof(GUID_DEVICEINTERFACE_LIST)/sizeof(GUID); i++)
    {
        NotificationFilter.dbcc_classguid = GUID_DEVICEINTERFACE_LIST[i];

        hDeviceNotify = RegisterDeviceNotification(
            (HANDLE)this->winId(),      // events recipient
            &NotificationFilter,        // type of device
            DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle
            );
        if (NULL == hDeviceNotify)
        {
            qDebug() << "RegisterDeviceNotification failed!";
            return false;
        }
    }

    return true;
}

#endif

void MainWindow::usb_device_is_connect()
{
    usb_communication->usb_device_start_receive(0x05);
}

void MainWindow::usb_device_is_disconnect()
{

}


